package com.zang.netty.io.nio;

import com.zang.netty.io.model.enums.SocketEnum;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @author Zhang Qiang
 * @Date 2019/7/19 15:49
 */
public class ClientTest {

    public static void main(String[] args) throws IOException {
        new Thread(new SendClient()).start();
    }

}


class SendClient implements Runnable{
    private SocketChannel socketChannel;
    private Selector selector;
    private volatile boolean stop;

    SendClient() throws IOException {
        socketChannel = SocketChannel.open();
        selector = Selector.open();
        socketChannel.configureBlocking(false);
    }

    public void run() {
        try {

            doConnect();

            // 循环
            while (!stop){

                selector.select(1000);
                Set<SelectionKey> keys = selector.keys();
                Iterator<SelectionKey> it = keys.iterator();
                SelectionKey key = null;

                while (it.hasNext()){
                    key = it.next();
                    it.remove();
                    handleKey(key);
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        if (selector!=null){
            try {
                selector.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

     /**
      * 执行连接
      */
    private void doConnect() throws IOException {
        if (socketChannel.connect(new InetSocketAddress(SocketEnum.LOCALHOST.getStr(), SocketEnum.NIO_PORT.getNum()))){
            socketChannel.register(selector, SelectionKey.OP_READ);

            // 连接成功即发送
            String sendMsg = "QUERY TIME ORDER";
            byte[] bytes = sendMsg.getBytes();
            ByteBuffer outBuffer = ByteBuffer.allocate(bytes.length);
            outBuffer.put(bytes);
            //写模式切换读模式
            outBuffer.flip();
            //发送消息
            socketChannel.write(outBuffer);
            if (!outBuffer.hasRemaining()){
                System.out.println("buffer清空，发送完毕");
            }
        }else {
            socketChannel.register(selector, SelectionKey.OP_CONNECT);
        }
    }

     /**
      * 处理消息 并发送 QUERY TIME ORDER
      */
    public void handleKey(SelectionKey key) throws IOException {
        if (key.isValid()){
            SocketChannel socketChannel = (SocketChannel) key.channel();
            //发送
            if (key.isConnectable()){
                //判断是否建立连接，然后发送消息
                if (socketChannel.finishConnect()){
                    socketChannel.register(key.selector(),SelectionKey.OP_READ);
                    String sendMsg = "QUERY TIME ORDER";
                    byte[] bytes = sendMsg.getBytes();
                    ByteBuffer outBuffer = ByteBuffer.allocate(bytes.length);
                    outBuffer.put(bytes);
                    //写模式切换读模式
                    outBuffer.flip();
                    //发送消息
                    socketChannel.write(outBuffer);
                    if (!outBuffer.hasRemaining()){
                        System.out.println("buffer清空，发送完毕");
                    }
                }
            }

            //读取
            if (key.isReadable()){
                ByteBuffer readBuffer = ByteBuffer.allocate(1024);
                int read = socketChannel.read(readBuffer);
                if (read > 0 ){
                    readBuffer.flip();
                    byte[] bytes = new byte[readBuffer.remaining()];
                    readBuffer.get(bytes);
                    String content = new String(bytes,"UTF-8");
                    System.out.println(content);
                    this.stop = true;
                }else if (read < 0){
                    key.cancel();
                    socketChannel.close();
                }
            }
        }
    }






}
